package com.yt.common.utils;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * httpClient工具类
 */
@Slf4j
public class HttpClientUtil {

    /**
     * 重写验证方法，取消检测ssl
     */
    private static final TrustManager truseAllManager = new X509TrustManager() {
        public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }

        public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }

        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    };
    private static HttpClientUtil instance = null;
    //    HttpHost proxy = new HttpHost("127.0.0.1",8888);
    private final RequestConfig requestConfig = RequestConfig.custom()
//            .setProxy(proxy)
            .setSocketTimeout(15000)
            .setConnectTimeout(15000)
            .setConnectionRequestTimeout(15000)
            .build();

    private HttpClientUtil() {
    }

    public static HttpClientUtil getInstance() {
        if (instance == null) {
            instance = new HttpClientUtil();
        }
        return instance;
    }

    public CloseableHttpClient getHttsClient() {
        try {
            SSLContext sslcontext = SSLContext.getInstance("TLS");
            sslcontext.init(null, new TrustManager[]{truseAllManager}, null);
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public HttpPost getHttpPost(String httpUrl) {
        HttpPost httpPost = new HttpPost(httpUrl);
        httpPost.setConfig(requestConfig);
        return httpPost;
    }

    /**
     * 发送 post请求
     *
     * @param httpUrl 地址
     * @param json    参数
     */
    public String sendHttpPostJson(String httpUrl, String json) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost(httpUrl);
            httpPost.setConfig(requestConfig);
            StringEntity entity = new StringEntity(json, "utf-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            httpClient = createHttpClient(httpUrl);
            response = httpClient.execute(httpPost);
            HttpEntity resEntity = response.getEntity();
            return EntityUtils.toString(resEntity, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeConn(httpClient, response);
        }
        return null;
    }

    public String sendHttpGetJson(String httpUrl) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            HttpGet httpGet = new HttpGet(httpUrl);
            httpGet.setConfig(requestConfig);
            httpClient = createHttpClient(httpUrl);
            response = httpClient.execute(httpGet);
            HttpEntity resEntity = response.getEntity();
            return EntityUtils.toString(resEntity, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeConn(httpClient, response);
        }
        return null;
    }

    public String sendUrlByJson(String urlString, Map<String, String> params, Map<String, String> headers) {
        return sendPostUrl(urlString, params, headers, "json");
    }

    public String sendUrlByForm(String urlString, Map<String, String> params, Map<String, String> headers) {
        return sendPostUrl(urlString, params, headers, "x-www-form-urlencoded");
    }

    public String sendPostUrl(String urlString, Map<String, String> params, Map<String, String> headers, String applicationType) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        // 执行
        try {
            HttpPost httppost = new HttpPost(urlString);

            if (headers != null) {
                for (Entry<String, String> entry : headers.entrySet()) {
                    httppost.addHeader(entry.getKey(), entry.getValue());
                }
            }

            if ("json".equals(applicationType)) {
                String paramsJson = JSON.toJSONString(params);
//                log.error("paramsJson----->:" + JSON.toJSONString(paramsJson));
                StringEntity stringEntity = new StringEntity(paramsJson, ContentType.create("application/json", "UTF-8"));
//                HttpEntity httpEntity = new StringEntity(paramsJson);
//                InputStream is =  stringEntity.getContent();
//
//                ByteArrayOutputStream baos = new ByteArrayOutputStream();
//
//                byte[] buffer = new byte[1024];
//                int len = -1;
//                while((len = is.read(buffer)) != -1){
//                    baos.write(buffer, 0, len);
//                }
//                is.close();
//                String s = new String(baos.toByteArray());

//                log.error("params----->:" + JSON.toJSONString(stringEntity));
                // 设置请求的数据
                httppost.setEntity(stringEntity);

            } else {
                List<NameValuePair> formparams = new ArrayList<>();
                if (params != null) {
                    for (Entry<String, String> entry : params.entrySet()) {
                        formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                    }
                }
                UrlEncodedFormEntity reqEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
                httppost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
                httppost.setEntity(reqEntity);
            }


//            log.error("headers----->:" + JSON.toJSONString(httppost.getAllHeaders()));
            httpClient = createHttpClient(urlString);
            response = httpClient.execute(httppost);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
//            log.error("response----->:" + JSON.toJSONString(responseContent));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeConn(httpClient, response);
        }
        return responseContent;
    }

    public String sendGetUrl(String urlString, Map<String, String> headers) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        // 执行
        try {
            HttpGet httpGet = new HttpGet(urlString);
            httpGet.setConfig(requestConfig);
            httpClient = createHttpClient(urlString);

            if (headers != null) {
                for (Entry<String, String> entry : headers.entrySet()) {
                    httpGet.addHeader(entry.getKey(), entry.getValue());
                }
            }

            response = httpClient.execute(httpGet);
            HttpEntity resEntity = response.getEntity();
            responseContent = EntityUtils.toString(resEntity, "UTF-8");

//            log.error("headers----->:" + JSON.toJSONString(httpGet.getAllHeaders()));
//            log.error("response----->:" + JSON.toJSONString(responseContent));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeConn(httpClient, response);
        }
        return responseContent;
    }

    private void closeConn(CloseableHttpClient httpClient, CloseableHttpResponse response) {
        try {
            // 关闭连接,释放资源
            if (response != null) {
                response.close();
            }
            if (httpClient != null) {
                httpClient.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private CloseableHttpClient createHttpClient(String httpUrl) throws Exception {
        CloseableHttpClient httpClient = null;
        if (httpUrl.startsWith("https:")) {
            SSLContext sslcontext = SSLContext.getInstance("TLS");
            sslcontext.init(null, new TrustManager[]{truseAllManager}, null);
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
            httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } else {
            httpClient = HttpClients.createDefault();
        }
        return httpClient;
    }
}
